From 561e9179370c6927160eb797e1dccc5351d13eb3 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 16 Nov 2010 14:09:13 +0000 Subject: [PATCH] x86: Clean up vcpu initialisation (especially xsave save area) Signed-off-by: Keir Fraser --- xen/arch/x86/domain.c | 68 +++++++++++++++----------------------- xen/arch/x86/i387.c | 25 ++++++++++++-- xen/include/asm-x86/i387.h | 5 +-- 3 files changed, 52 insertions(+), 46 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 87439f8de9..6cdb6d85c6 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -343,60 +343,44 @@ int vcpu_initialise(struct vcpu *v) paging_vcpu_init(v); - if ( cpu_has_xsave ) - { - /* XSAVE/XRSTOR requires the save area be 64-byte-boundary aligned. */ - void *xsave_area = _xmalloc(xsave_cntxt_size, 64); - if ( xsave_area == NULL ) - return -ENOMEM; - - xsave_init_save_area(xsave_area); - v->arch.xsave_area = xsave_area; - v->arch.xcr0 = XSTATE_FP_SSE; - v->arch.xcr0_accum = XSTATE_FP_SSE; - } + v->arch.perdomain_ptes = perdomain_ptes(d, v); + + spin_lock_init(&v->arch.shadow_ldt_lock); + + if ( (rc = xsave_alloc_save_area(v)) != 0 ) + return rc; if ( is_hvm_domain(d) ) { if ( (rc = hvm_vcpu_initialise(v)) != 0 ) - { - xfree(v->arch.xsave_area); - return rc; - } + xsave_free_save_area(v); + return rc; } - else - { - /* PV guests by default have a 100Hz ticker. */ - if ( !is_idle_domain(d) ) - v->periodic_period = MILLISECS(10); - /* PV guests get an emulated PIT too for video BIOSes to use. */ - if ( !is_idle_domain(d) && (v->vcpu_id == 0) ) - pit_init(v, cpu_khz); + /* PV guests by default have a 100Hz ticker. */ + if ( !is_idle_domain(d) ) + v->periodic_period = MILLISECS(10); - v->arch.schedule_tail = continue_nonidle_domain; - v->arch.ctxt_switch_from = paravirt_ctxt_switch_from; - v->arch.ctxt_switch_to = paravirt_ctxt_switch_to; + /* PV guests get an emulated PIT too for video BIOSes to use. */ + if ( !is_idle_domain(d) && (v->vcpu_id == 0) ) + pit_init(v, cpu_khz); - if ( is_idle_domain(d) ) - { - v->arch.schedule_tail = continue_idle_domain; - v->arch.cr3 = __pa(idle_pg_table); - } + v->arch.schedule_tail = continue_nonidle_domain; + v->arch.ctxt_switch_from = paravirt_ctxt_switch_from; + v->arch.ctxt_switch_to = paravirt_ctxt_switch_to; - v->arch.guest_context.ctrlreg[4] = - real_cr4_to_pv_guest_cr4(mmu_cr4_features); + if ( is_idle_domain(d) ) + { + v->arch.schedule_tail = continue_idle_domain; + v->arch.cr3 = __pa(idle_pg_table); } - v->arch.perdomain_ptes = perdomain_ptes(d, v); - - spin_lock_init(&v->arch.shadow_ldt_lock); + v->arch.guest_context.ctrlreg[4] = + real_cr4_to_pv_guest_cr4(mmu_cr4_features); - rc = 0; - if ( is_pv_32on64_vcpu(v) ) - rc = setup_compat_l4(v); + rc = is_pv_32on64_vcpu(v) ? setup_compat_l4(v) : 0; if ( rc ) - xfree(v->arch.xsave_area); + xsave_free_save_area(v); return rc; } @@ -406,7 +390,7 @@ void vcpu_destroy(struct vcpu *v) if ( is_pv_32on64_vcpu(v) ) release_compat_l4(v); - xfree(v->arch.xsave_area); + xsave_free_save_area(v); if ( is_hvm_vcpu(v) ) hvm_vcpu_destroy(v); diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c index 1398b8fa5b..82dd88e920 100644 --- a/xen/arch/x86/i387.c +++ b/xen/arch/x86/i387.c @@ -204,12 +204,33 @@ void xsave_init(void) } } -void xsave_init_save_area(void *save_area) +int xsave_alloc_save_area(struct vcpu *v) { - memset(save_area, 0, xsave_cntxt_size); + void *save_area; + + if ( !cpu_has_xsave ) + return 0; + + /* XSAVE/XRSTOR requires the save area be 64-byte-boundary aligned. */ + save_area = _xmalloc(xsave_cntxt_size, 64); + if ( save_area == NULL ) + return -ENOMEM; + memset(save_area, 0, xsave_cntxt_size); ((u32 *)save_area)[6] = 0x1f80; /* MXCSR */ *(uint64_t *)(save_area + 512) = XSTATE_FP_SSE; /* XSETBV */ + + v->arch.xsave_area = save_area; + v->arch.xcr0 = XSTATE_FP_SSE; + v->arch.xcr0_accum = XSTATE_FP_SSE; + + return 0; +} + +void xsave_free_save_area(struct vcpu *v) +{ + xfree(v->arch.xsave_area); + v->arch.xsave_area = NULL; } /* diff --git a/xen/include/asm-x86/i387.h b/xen/include/asm-x86/i387.h index ba773e99ed..0e01d1604d 100644 --- a/xen/include/asm-x86/i387.h +++ b/xen/include/asm-x86/i387.h @@ -17,8 +17,9 @@ extern unsigned int xsave_cntxt_size; extern u64 xfeature_mask; -extern void xsave_init(void); -extern void xsave_init_save_area(void *save_area); +void xsave_init(void); +int xsave_alloc_save_area(struct vcpu *v); +void xsave_free_save_area(struct vcpu *v); #define XSTATE_FP (1 << 0) #define XSTATE_SSE (1 << 1) -- 2.30.2